/*
 www.pipoisu.com
 Copyright (c) 2011.  All rights reserved.

 File     : pipo.h
 Author(s): Erez Raviv

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program. If not, see <http://www.gnu.org/licenses/>.
*/


#ifndef PIPO_H
#define PIPO_H


#include <inttypes.h>
#include <string.h>
#include <stdlib.h>

//#include <stddef.h>
//#include <avr/io.h>

//#include <avr/pgmspace.h>

#include <avr/eeprom.h>
//#include <avr/sleep.h>
//#include <avr/interrupt.h>

//#include <util/delay.h>
#include <util/atomic.h>
//#define pgm_read_adr(address_short) pgm_read_word(address_short)
#include <avr/wdt.h>
//#include <math.h>


//F_CPU defined in makefile


//#define PIN_OUTPUT 1
//#define PIN_INPUT  0
//#define PIN_NODEF  0

// pin definitions
//PB0 - OUTPUT - PWMOUT 1 / PCINT0
//PB1 - OUTPUT - PWMOUT 2 / PCINT1 - OC1A
//PB2 - OUTPUT - PWMOUT 5 / PCINT2 - OC1B
//PB3 - OUTPUT - PWMOUT 6 / PCINT3 - OC2A  / MOSI
//PB4 - OUTPUT - PWMOUT 7 / PCINT4 / MISO
//PB5 - OUTPUT - PWMOUT 8 / PCINT5 / SCK
//PB6 - XTAL 1
//PB7 - XTAL 2

//PC0 - OUTPUT - PWMOUT 3 / PCINT 8
//PC1 - OUTPUT - PWMOUT 4 / PCINT 9
//PC2 - OUTPUT - Red LED
//PC3 - OUTPUT - Green LED
//PC4 - TWI - SDA
//PC5 - TWI - SCL
//PC6 - RESET
//PC7 - ?

//PD0 - OUTPUT - UART RXD - PWMOUT 1 / RXD / PCINT 16
//PD1 - OUTPUT - UART TXD - PWMOUT 2 / TXD / PCINT 17
//PD2 - INPUT - PWMIN 1 / PCINT 18
//PD3 - INPUT - PWMIN 2 / PCINT 19 / OC2B
//PD4 - INPUT - PWMIN 3 / PCINT 20
//PD5 - INPUT - PWMIN 4 / PCINT 21 / OC0B
//PD6 - INPUT - PWMIN 5 / PCINT 22 / OC0A
//PD7 - INPUT - PWMIN 6 / PCINT 23



//LED definitions
#define PORT_LED_RED      PORTC
#define BIT_LED_RED       (1<<PC2)
#define PORT_LED_GREEN    PORTC
#define BIT_LED_GREEN     (1<<PC3)

//PWM_IN definitions - depends on mode12c
#define PWM_IN_MASK  ((PIND & 0xFC) >> 2) //remember to shift 2 places
#define PCMSK0_BITS  (0) //bits on port B
#define PCMSK1_BITS  (0)  //bits on port C
#define PCMSK2_BITS  (((1<<PCINT18) | (1<<PCINT19) | (1<<PCINT20) | (1<<PCINT21) | (1<<PCINT22) | (1<<PCINT23))) // no bits set on portd
#define PCICR_BITS   ((1<<PCIE2)) //enable PC interrupt on port D

#define PORT_B_SETUP	(0x3F)  // 0..5 outputs
#define PORT_B_INIT     (0x00)  // set up pullups
#define PORT_C_SETUP	(0x0F)  // 2 leds are outputs
#define PORT_C_INIT	    (0x00)  // DO NOT ENABLE PULLUPS ON SDA/SCL!
#define PORT_D_SETUP	(0x00)  // UART
#define PORT_D_INIT	    (0xFC)  // DO NOT ENABLE PULLUPS ON UART

#define OUTPUT1_OFF      PORTB &= ~(1<<0)
#define OUTPUT2_OFF      PORTB &= ~(1<<1)
#define OUTPUT3_OFF      PORTC &= ~(1<<0)
#define OUTPUT4_OFF      PORTC &= ~(1<<1)
#define OUTPUT5_OFF      PORTB &= ~(1<<2)
#define OUTPUT6_OFF      PORTB &= ~(1<<3)
#define OUTPUT7_OFF      PORTB &= ~(1<<4)
#define OUTPUT8_OFF      PORTB &= ~(1<<5)

#define LED_RED_ON      PORT_LED_RED	|=  BIT_LED_RED
#define LED_RED_OFF     PORT_LED_RED	&= ~BIT_LED_RED
#define LED_RED_FLIP    PORT_LED_RED	^=  BIT_LED_RED
#define LED_RED_IS_ON   (PORT_LED_RED	&	BIT_LED_RED)
#define LED_GREEN_ON    PORT_LED_GREEN	|=  BIT_LED_GREEN
#define LED_GREEN_OFF   PORT_LED_GREEN	&= ~BIT_LED_GREEN
#define LED_GREEN_FLIP  PORT_LED_GREEN	^=  BIT_LED_GREEN
#define LED_GREEN_IS_ON (PORT_LED_GREEN	&	BIT_LED_GREEN)

#define RESX            1024
#define RESXl           1024l
#define RESXu           1024u
#define RESXsh          10 //shift value

#define TICKS_PER_MSEC  2000        // (16000/8)
#define TICKS_PER_SEC   2000000.0f  // (16000/8 * 1000) = 2 milion ticks

#define PWM_FRAME_MSEC   5   // length of main loop = PWM frame length - must be long enough to complete calculation
#define PWM_FRAME_USEC   0
#define PWM_FRAME_TICKS  (TICKS_PER_MSEC*PWM_FRAME_MSEC + PWM_FRAME_USEC*2)
#define PWM_MIDFRAME     (TICKS_PER_MSEC*3/2)  // 1.5 msec
#define PWM_MAX          (PWM_MIDFRAME + RESX)
#define PWM_MIN          (PWM_MIDFRAME - RESX)
#define PWM_STICK_MIN    (PWM_MIDFRAME - (RESX*5/4)) // allow for +/- 125% from TX
#define PWM_STICK_MAX    (PWM_MIDFRAME + (RESX*5/4))

#define STICK_LIMIT		300		// defines the point at which a stick is considered to be @ max travel
#define STICK_HI		(RESX-STICK_LIMIT)	//defines stick @ max
#define STICK_LO		(STICK_LIMIT-RESX)	//defines stick @ min

#define NUMPPM_IN		6
#define NUMPPM_OUT  	8  // max number of output ppm channels

#define CALIB_SAMPLES	16  //sensor samples for offset.   Each sample takes 0.1sec (100ms) at startup.
#define STARTUP_DELAY	500 //500 msec startup delay

#define G25MSEC_SPAN    (TICKS_PER_MSEC * 25L) // 25msec timer


/*************************************************************************
 Macros
*************************************************************************/
#define MIN(a,b)           ( ((a)<(b)) ? (a) : (b) )
#define MAX(a,b)           ( ((a)>(b)) ? (a) : (b) )
#define MINMAX(x,min,max)  ( MIN(MAX((x),(min)),(max)) )
#define INTMINMAX(x)       ( MINMAX(x,-0x7FFF,0x7FFF)  )
#define CONSTRAIN(x,a)     ( MINMAX(x,-(a),(a)) )
#define SWAP(a,b)          ( ((a) ^ (b)) && ((b) ^= (a) ^= (b), (a) ^= (b)) )


extern int16_t attitudeCMD[3];
extern uint16_t deltaT_int;
extern uint8_t magnetometer;
extern volatile uint16_t g25msec;
extern volatile uint8_t flashRedLed;
extern uint16_t maxPWMPeriod;



#endif // PIPO_H
